package com.deer.wms.base.system.web.zhBusiness.in;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONArray;
import com.deer.wms.base.system.finalUtil.*;
import com.deer.wms.base.system.model.BillInRecord;
import com.deer.wms.base.system.model.bill.*;
import com.deer.wms.base.system.model.box.BoxInfo;
import com.deer.wms.base.system.model.box.BoxItem;
import com.deer.wms.base.system.model.item.ItemInfo;
import com.deer.wms.base.system.model.task.TaskInfo;
import com.deer.wms.base.system.model.task.TaskInfoCriteria;
import com.deer.wms.base.system.model.task.TaskInfoDto;
import com.deer.wms.base.system.model.task.TaskInfoHistoryDto;
import com.deer.wms.base.system.model.ware.CellInfo;
import com.deer.wms.base.system.model.zh.*;
import com.deer.wms.base.system.service.BillInRecordService;
import com.deer.wms.base.system.service.bill.*;
import com.deer.wms.base.system.service.box.*;
import com.deer.wms.base.system.service.item.IItemInfoService;
import com.deer.wms.base.system.service.rocket.RocketService;
import com.deer.wms.base.system.service.task.BillInTaskInfoService;
import com.deer.wms.base.system.service.task.ITaskInfoService;
import com.deer.wms.base.system.service.task.PickTaskService;
import com.deer.wms.base.system.service.task.TaskInfoHistoryService;
import com.deer.wms.base.system.service.ware.ICellInfoService;
import com.deer.wms.base.system.service.zh.*;
import com.deer.wms.base.system.util.JedisServiceUtil;
import com.deer.wms.base.system.util.RedisUtil;
import com.deer.wms.base.system.web.zhBusiness.business.QualityController;
import com.deer.wms.common.core.result.CommonCode;
import com.deer.wms.common.core.result.Result;
import com.deer.wms.common.core.result.ResultGenerator;
import com.deer.wms.common.json.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author 李帅辰
 * @date 2021/5/24 16:55
 */
@RestController
@RequestMapping("/zhBillIn")
@Slf4j
public class zhBillInController {
    @Autowired
    private ITaskInfoService taskInfoService;//任务处理层

    @Autowired
    private TaskInfoHistoryService taskInfoHistoryService;

    @Autowired
    private IBillInDetailService billInDetailService;//入库单明细

    @Autowired
    private IBillInMasterService billInMasterService;


    @Autowired
    private IBoxItemService boxItemService;//组盘

    @Autowired
    private IngotIocusService ingotIocusService;


    @Autowired
    private IItemInfoService itemInfoService;

    @Autowired
    private BoxInfoService boxInfoService;

    @Autowired
    private ICellInfoService cellInfoService;

    @Autowired
    private JedisServiceUtil jedisServiceUtil;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private ShelfPlanService shelfPlanService;

    @Autowired
    private BillInTaskInfoService billInTaskInfoService;

    @Autowired
    private QualityService qualityService;

    @Autowired
    private PickTaskService pickTaskService;

    @Autowired
    private QualityController qualityController;

    @Autowired
    private BoxItemExceptionService boxItemExceptionService;

    @Autowired
    private BillInRecordService billInRecordService;

    @Autowired
    private ZhMesService zhMesService;

    @Autowired
    private BillInExceptionRecordService billInExceptionRecordService;

    @Autowired
    private IMaterialDetailService materialDetailService;



    /**
     *入库下发任务，分配存放的位置  ,判断该晶棒编质检是否为异常
     * @author 李帅辰
     * @date 2021/5/27 17:31
     * @return java.util.Map<java.lang.String, java.lang.String>
     */
    @PostMapping("/allotCell")
    @ResponseBody
    @Transactional
    public Result allotCell(String param){
        boolean saveResult= qualityController.materialQuality(param);
        if(saveResult) {
            Quality quality = JSONArray.parseObject(param, Quality.class);//获取到任务，转换格式
            //0表示OK， 1表示NG，3表示灰度异常，4表示长度异常，5表示宽度异常，6表示位置异常
            //先判断质检数据
            String materialId = quality.getCode();//获取晶棒编码
            if (quality.getResult() == 0) {
                return this.allocation(materialId);
            }
            //不合格
            //此时还需要把当前晶棒的存储信息转移到异常存放区
            BoxItemException boxItemException = new BoxItemException();
            BillInDetailDto billInDetailDto = billInDetailService.selectBillInDetailByMaterialId(materialId);
            boxItemException.setState(1);//1 为待确认
            boxItemException.setType(2);//2标识为质检不合格
            //boxItemException.setBillInMaterialDetailId(billInDetailDto.getBillInMaterialDetailId());
            boxItemException.setAreaId(AreaInfoId.AREAINFO_EXCEPTION);
            boxItemExceptionService.saveBoxItemException(boxItemException);
            return this.playTask(1, materialId, -1,billInDetailDto);//下发异常任务
        }
        return ResultGenerator.genFailResult(CommonCode.QUALITY_ERROR);
    }

    /**
     * 入库到达扫码点，WCS请求，返回状态码、任务号  data为负数时标识位WCS需要排出到异常排出点
     * @author 李帅辰
     * @date 2021/6/7 10:54
     * @return com.deer.wms.common.core.result.Result
     */
    @PostMapping("/billInScan")
    @ResponseBody
    @Transactional
    public Result billInScan(@RequestBody ZhItem zhItem){
        log.info("入库扫码点晶棒编码"+zhItem.getMaterialId());
        String materialId = zhItem.getMaterialId();//晶棒编码
        BillInDetailDto billInDetailDto = billInDetailService.selectBillInDetailByMaterialId(materialId);
        IngotIocus ingotIocus = new IngotIocus(materialId,SiteInfo.BILLIN_THIRDLY,"WCS","wcs传递的晶棒"+materialId,"");//晶棒时间点信息录入
        ingotIocusService.saveIngotIocus(ingotIocus);
        //判断是否为回流入库，以晶棒ID查询晶棒状态是否为已检（3），不是的话，则为回流入库
//        if (billInDetailDto.getBillInState()!=3){
//            TaskInfoDto billInError = billInTaskInfoService.findBillInError(materialId);
//            if (billInError.getType()==2){
//                return  ResultGenerator.genBillSuccessResult(-1,billInError.getTaskNumber(),"异常排出任务");
//            }
//            //说明是回流入库
//            TaskInfoDto taskInfoDto = new TaskInfoDto();//任务对象
//            //taskInfoDto.setsFloor(-1);
//            //taskInfoDto.setsPai(-1);
//            long taskNumber = taskInfoService.generateTaskNumber();//设置任务号
//            taskInfoDto.setTaskNumber(taskNumber);
//            taskInfoDto.setType(TaskInfoState.BILLINBACKFLOW_TYPE);//任务类型
//            taskInfoDto.setState(TaskInfoState.STATE_ZERO);//状态
//            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//            taskInfoDto.setTaskStartTime(simpleDateFormat.format(new Date()));
//            billInTaskInfoService.insertTaskInfo(taskInfoDto);
//            String billInKey = BillRedisKey.BILLINTASKINFO_KEY + taskNumber;
//            jedisServiceUtil.set(billInKey, JSONArray.toJSONString(taskInfoDto));
//            log.info("回流入库下发的任务号"+taskNumber);
//            BillInDetail billInDetail = new BillInDetail();
//            billInDetail.setBillInState(6);
//            billInDetail.setBillInDetailId(billInDetailDto.getBillInDetailId());
//            int i = billInDetailService.updateBillInInfo(billInDetail);
////          ShelfPlan shelfPlan = new ShelfPlan();
////          shelfPlan.setShelfId(taskInfoDto.getShelfId());
////          String shelfCode = shelfPlanService.findShelfPlanByshelfPlan(shelfPlan).getShelfCode();
//
//            CacheLine  cacheLine =new CacheLine();
//            cacheLine.setMaterialId(taskInfoDto.getMaterialId());
//            cacheLine.setStockId("EX_AREA");
//            cacheLine.setUserId("WMS");
//            cacheLine.setStockInTime(DateUtil.now());//入库时间，12位，YYMMDDHHMMSS，MES根据入库时间排序
//            String resBack = zhMesService.CacheLineLocationMes(cacheLine);
//            log.info("回流入库的晶棒经过扫码点,回流晶棒id:{},同步回流晶棒到MES接口,MES返回结果为:{}",taskInfoDto.getMaterialId(),resBack);
//            IngotIocus ingotIocus1 = new IngotIocus(taskInfoDto.getMaterialId(),SiteInfo.BILLIN_THIRDLY,"MES",resBack,JSONArray.toJSONString(cacheLine));//晶棒时间点信息录入
//            ingotIocusService.saveIngotIocus(ingotIocus);
//            return  ResultGenerator.genBillSuccessResult(-1,taskNumber,"回流入库任务");
//        }
        //修改晶棒状态
        BillInDetail billInDetail = new BillInDetail();
        //billInDetail.setBillInState(4);
        billInDetail.setBillInDetailId(billInDetailDto.getBillInDetailId());
        billInDetailService.updateBillInInfo(billInDetail);
        TaskInfo taskInfo = billInTaskInfoService.selectByMaterialId(materialId);
        return  ResultGenerator.genBillSuccessResult(1,taskInfo.getTaskNumber(),"采购入库任务");
    }


    /**
     *晶棒到达异常排出口,扫描晶棒编码查询任务信息
     * @author 李帅辰
     * @date 2021/6/7 14:52
     * @return com.deer.wms.common.core.result.Result
     */
    @PostMapping("/findTaskInfo")
    @ResponseBody
    public  TaskInfoDto findTaskInfo(@RequestBody ZhItem zhItem){
        return  billInTaskInfoService.findBillInError(zhItem.getMaterialId());
    }

    /**
     *异常排出口，手持机操作接口
     * @author 李帅辰
     * @date 2021/6/8 17:22
     * @return com.deer.wms.common.core.result.Result
     */
    @PostMapping("/ErrorBillIn")
    @ResponseBody
    @Transactional
    public Result updateErrorBillIn(@RequestBody ZhItem zhItem){
        log.info("异常口扫码点晶棒编码"+zhItem.getMaterialId());
        String materialId = zhItem.getMaterialId();//晶棒编码
        TaskInfoDto billInError = billInTaskInfoService.findBillInError(materialId);
        //同步任务
        TaskInfo taskInfo = billInTaskInfoService.selectByMaterialId(materialId);
        taskInfoHistoryService.saveTaskInfoHistory(taskInfo);//任务完成同步到历史表
        billInTaskInfoService.deleteTaskInfoById(taskInfo.getId());//删除已完成的任务表
        Integer type = billInError.getType();
        if (type==3){
            //回流任务
            return this.allocation(materialId);
        }
        //修改异常区库存信息
        BoxItemException boxItemException = new BoxItemException();
        boxItemException.setState(2);
        boxItemException.setMaterialId(materialId);
        boxItemExceptionService.updateBoxItemExceptionTime(boxItemException);
        //新增异常区入库记录
        MaterialDetail materialDetailByMaterialId = materialDetailService.findMaterialDetailByMaterialId(materialId);
        BillInExceptionRecord billInExceptionRecord = new BillInExceptionRecord();
        billInExceptionRecord.setBillInMaterialDetailId(materialDetailByMaterialId.getId());
        billInExceptionRecordService.saveBillInExceptionRecord(billInExceptionRecord);
        IngotIocus ingotIocus = new IngotIocus(materialId,SiteInfo.BILLIN_FIFTH,"WCS","wcs传递的晶棒编码"+materialId,"");//晶棒时间点信息录入
        ingotIocusService.saveIngotIocus(ingotIocus);
        return  ResultGenerator.genBillSuccessResult();
    }


    /**
     *分配货位的方法
     * @author 李帅辰
     * @date 2021/6/10 14:23
     * @return com.deer.wms.common.core.result.Result
     */
    @Transactional
    public Result allocation(String materialId){
        //查询该方棒的品规类型
        BillInDetailDto billInDetailDto = billInDetailService.selectBillInDetailByMaterialId(materialId);
        if (null == billInDetailDto){
            return ResultGenerator.genFailResult(CommonCode.PARAMETER_ERROR);
        }
        //String specId = billInDetailDto.getSpecId();//单晶规格
        //Integer assemblyType = billInDetailDto.getAssemblyType();//拼棒类型
        //获取到拼柜类型后，再查询应该存放的缓存线
        ShelfPlan shelfPlan = new ShelfPlan();
        //shelfPlan.setAssemblyType(assemblyType);
        //shelfPlan.setSpec(specId);
        ShelfPlan shelfPlanByshelfPlan = shelfPlanService.findShelfPlanByshelfPlan(shelfPlan);
        if (null == shelfPlanByshelfPlan){
            return ResultGenerator.genFailResult(CommonCode.PARAMETER_ERROR);
        }
        //判断是否有货位
        boolean count = shelfPlanService.getCount(shelfPlan);
        if (count) {
            //首先获取到，不在任务中的空闲巷道
            List<ShelfPlan> quantityAndShelf = shelfPlanService.findQuantityAndShelf(shelfPlan);
            if (0 != quantityAndShelf.size() && null != quantityAndShelf) {
                for (ShelfPlan plan : quantityAndShelf) {
                    if (plan.getQuantity() < 1) {
                        continue;
                    }
                    //下发任务
                    return this.playTask(plan.getShelfId(), materialId, 1,billInDetailDto);
                }
            }
            //没有空闲巷道，随机找一个缓存线下发任务
            List<ShelfPlan> shelfPlanList = shelfPlanService.findShelfPlanList(shelfPlan);
            int randomIndex = new Random().nextInt(shelfPlanList.size());
            ShelfPlan shelfPlan1 = shelfPlanList.get(randomIndex);
            //下发任务
            return this.playTask(shelfPlan1.getShelfId(), materialId, 1,billInDetailDto);
        }
        return ResultGenerator.genFailResult(CommonCode.CELLCOUNT_ERROR);
    }



    /**
     *下发任务
     * @param shelfId
     * @param materialId
     * @param result
     * @param billInDetailDto
     * @author 李帅辰
     * @date 2021/6/5 15:50
     * @return com.deer.wms.common.core.result.Result
     */
    @Transactional
    public Result playTask(Integer shelfId,String materialId,int result,BillInDetailDto billInDetailDto) {
        IngotIocus ingotIocus = new IngotIocus(materialId,SiteInfo.BILLIN_SECOND,"WCS","wcs传递的晶棒"+materialId,"");//晶棒时间点信息录入
        ingotIocusService.saveIngotIocus(ingotIocus);
        TaskInfoDto taskInfoDto = new TaskInfoDto();//任务对象
        if (result == -1) {
            //taskInfoDto.setsFloor(-1);
            //taskInfoDto.setsPai(-1);
            taskInfoDto.setType(TaskInfoState.BILLINERROR_TYPE);//任务类型
        } else{
            CellInfo cellInfo = cellInfoService.findPaiAndfloorByShelfId(shelfId);
            //taskInfoDto.setsFloor(cellInfo.getsFloor());
            //taskInfoDto.setsPai(cellInfo.getsPai());
            taskInfoDto.setShelfId(shelfId);
            taskInfoDto.setType(TaskInfoState.BILLIN_TYPE);//任务类型
        }
        long taskNumber = taskInfoService.generateTaskNumber();//设置任务号
        taskInfoDto.setShelfId(shelfId);
        taskInfoDto.setTaskNumber(taskNumber);
        taskInfoDto.setState(TaskInfoState.STATE_ZERO);//状态
        taskInfoDto.setBillInDetailId(billInDetailDto.getBillInDetailId());//明细ID
        taskInfoDto.setBillId(billInDetailDto.getBillId());//入库单ID
        //taskInfoDto.setQuantity(billInDetailDto.getQuantity());
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        taskInfoDto.setTaskStartTime(simpleDateFormat.format(new Date()));
        //taskInfoDto.setMaterialId(materialId);
        int i1 = billInTaskInfoService.insertTaskInfo(taskInfoDto);
        String billInKey = BillRedisKey.BILLINTASKINFO_KEY + taskNumber;
        jedisServiceUtil.set(billInKey, JSONArray.toJSONString(taskInfoDto));
        //修改单据明细状态
        BillInDetail billInDetail = new BillInDetail();
        if (i1==0){
            return ResultGenerator.genFailResult(CommonCode.CELLCOUNT_ERROR);
        }
        if (result == -1) {
            //修改晶棒状态
            //billInDetail.setBillInState(6);
            billInDetail.setBillInDetailId(billInDetailDto.getBillInDetailId());
            billInDetailService.updateBillInInfo(billInDetail);
            return  ResultGenerator.genBillSuccessResult(1,taskNumber,"异常排除任务下发成功");
        }
        //billInDetail.setBillInState(3);
        billInDetail.setBillInDetailId(billInDetailDto.getBillInDetailId());
        billInDetailService.updateBillInInfo(billInDetail);
        return  ResultGenerator.genBillSuccessResult(1,taskNumber,"采购入库任务下发成功");
    }



    /**
     * 入库完成，更新库存信息
     * @author 李帅辰
     * @date 2021/6/3 18:10
     * @return com.deer.wms.common.core.result.Result
     */
    @GetMapping("/updateBox")
    @ResponseBody
    @Transactional
    public Result updateBox() throws Exception {
        String key = BillRedisKey.UPDATEBILLIN_KEY;
        List<String> listAllByindex = jedisServiceUtil.getListAllByindex(key, 0, -1);
        for (String taskNumber : listAllByindex) {
            int saveBoxItemRe =1;
            int saveBillInRecordRe=1;
            int saveTaskHisRe =1;
            int delTaskRe =1;
            TaskInfoDto taskInfoDto = billInTaskInfoService.getAllUpdateByTaskNumber(Long.parseLong(taskNumber));//通过任务号查询更新报表所需要的数据

            CellInfo cellBySheId = cellInfoService.getCellBySheId(taskInfoDto.getShelfId());//缓存线入库更新货位时查询货位
            Integer cellId = cellBySheId.getCellId();
            cellBySheId.getCellCode();
            BoxItem boxItem = new BoxItem();
            BoxInfo boxInfo = new BoxInfo();
            BillInRecord billInRecord = new BillInRecord();
            BillInDetail billInDetail = new BillInDetail();
            billInDetail.setBillInDetailId(taskInfoDto.getBillInDetailId());//ID
            //billInDetail.setQuantityReceived(taskInfoDto.getQuantity());//数量
            //更新库存
            //boxItem.setBoxCode("TP"+taskInfoDto.getMaterialId());
            boxItem.setBatch(taskInfoDto.getBatch());
            //boxItem.setItemCode(taskInfoDto.getItemCode());
            boxItem.setBillInDetailId(taskInfoDto.getBillInDetailId());
            //boxItem.setPd(taskInfoDto.getPdTime());
            boxItem.setWareId(1220);
            boxItem.setState(0);
            //boxItem.setQuantity(1);
            BoxItem  verifyBoxItem= boxItemService.verifyBoxItem(boxItem);
            if(null ==verifyBoxItem){
                saveBoxItemRe = boxItemService.insertBoxItem(boxItem);
            }


            //boxInfo.setBoxCode("TP"+taskInfoDto.getMaterialId());
            boxInfo.setBoxState(BoxInfoState.BOXINFO_STATE_ONT);//0-不在货位 1-货位上  2-任务中
            boxInfo.setHasGoods(BoxInfoState.BOXINFO_GOODS_ONT);//   0-无货 1-有货
            boxInfo.setBoxCellId(cellId);//货位
            boxInfo.setBoxType(2);//类型：1-料箱  2-托盘
            boxInfoService.save(boxInfo);

            //货位以及状态 cellInfo
            CellInfo cellInfo = new CellInfo();
            cellInfo.setState(CellInfoState.STATE_ONT);//状态  ：0-无托盘；1-有货；2-出库中；3-入库中；4故障
            cellInfo.setCellId(cellId);
            int editCellInfo = cellInfoService.updateCellInfo(cellInfo);
            //修改晶棒状态
            BillInDetail bill = new BillInDetail();
            //bill.setBillInState(5);
            bill.setBillInDetailId(taskInfoDto.getBillInDetailId());
            billInDetailService.updateBillInInfo(bill);

            //同步入库报表
            billInRecord.setBillInDetailId(taskInfoDto.getBillInDetailId());//出库单id
//            billInRecord.setAcceptQuantity(taskInfoDto.getQuantity());//入库数量
//            billInRecord.setBoxCode(taskInfoDto.getBoxCode());
//            billInRecord.setBarCode(taskInfoDto.getBarCode());
            billInRecord.setBatch(taskInfoDto.getBatch());
            BillInRecord verifyBillInRecord = billInRecordService.verifyBillInRecord(billInRecord);
            if(null==verifyBillInRecord){
                saveBillInRecordRe = billInRecordService.insertBillInRecord(billInRecord);
            }
            //同步入库单状态
            BillInMaster billInMaster =new BillInMaster();
            billInMaster.setState(BillState.BILLIN_STATE_FOUR);//已入库
            billInMaster.setBillId(taskInfoDto.getBillId());
            int editBillMaRe = billInMasterService.updateBillInMaster(billInMaster);

            //同步任务表
            Integer id= taskInfoDto.getId();
            TaskInfoCriteria criteria =new TaskInfoCriteria();
//            criteria.setBoxCode(taskInfoDto.getBoxCode());
            criteria.setBillInDetailId(taskInfoDto.getBillInDetailId());
            TaskInfoHistoryDto taskInfoHistoryDto = taskInfoHistoryService.verifTaskInfoHistory(criteria);
            if(null==taskInfoHistoryDto){
                saveTaskHisRe = taskInfoHistoryService.saveTaskInfoHistory(billInTaskInfoService.selectTaskInfoById(id));//任务完成同步到历史表
                delTaskRe = billInTaskInfoService.deleteTaskInfoById(id);//删除已完成的任务表
            }


           //入库任务完成，记录晶棒信息
            //IngotIocus ingotIocus = new IngotIocus(taskInfoDto.getMaterialId(),SiteInfo.BILLIN_SECOND,"WCS","需要更新的晶棒编码"+taskInfoDto.getTaskNumber(),"");//晶棒时间点信息录入
            //ingotIocusService.saveIngotIocus(ingotIocus);
            // 此处待修改，以上全部测试成功
/*
            //对接mes 1:晶棒入缓存线，发送位置信息给MES
            ShelfPlan shelfPlan = new ShelfPlan();
            shelfPlan.setShelfId(taskInfoDto.getShelfId());
            String shelfCode = shelfPlanService.findShelfPlanByshelfPlan(shelfPlan).getShelfCode();
            CacheLine  cacheLine =new CacheLine();
            cacheLine.setMaterialId(taskInfoDto.getMaterialId());
            cacheLine.setStockId(shelfCode);
            cacheLine.setUserId("WMS");
            cacheLine.setStockInTime(DateUtil.now());//入库时间，12位，YYMMDDHHMMSS，MES根据入库时间排序
            zhMesService.CacheLineLocationMes(cacheLine);

            IngotIocus ingotIocus1 = new IngotIocus(taskInfoDto.getMaterialId(),SiteInfo.BILLIN_SECOND,"MES","",JSONArray.toJSONString(cacheLine));//晶棒时间点信息录入
            ingotIocusService.saveIngotIocus(ingotIocus);


            //WMS同步单晶信息给MES
            List<ZhItem> zhItems = new ArrayList<>();
            ZhItem zhItem  = new ZhItem();
            zhItem.setMaterialId(taskInfoDto.getMaterialId());
            zhItem.setStockInTime("");//入库时间
            zhItems.add(zhItem);


            //MES 晶棒缓存线同步库存信息给MES
            BillInUpdateBox billInUpdateBox = new BillInUpdateBox();
            billInUpdateBox.setStockId(shelfCode);
            billInUpdateBox.setInfo(zhItems);
            JSONArray.toJSONString(billInUpdateBox);
            IngotIocus ingotIocus2 = new IngotIocus(taskInfoDto.getMaterialId(),SiteInfo.BILLIN_SECOND,"MES","", JSONArray.toJSONString(bill));//晶棒时间点信息录入
            ingotIocusService.saveIngotIocus(ingotIocus);*/
       }
        return  ResultGenerator.genSuccessResult();
    }
}
